Skip to content

Refactor tinygrid/ercot.py into modular subpackage#2

Merged
kvkenyon merged 6 commits into
mainfrom
refactor/ercot-subpackage
Dec 29, 2025
Merged

Refactor tinygrid/ercot.py into modular subpackage#2
kvkenyon merged 6 commits into
mainfrom
refactor/ercot-subpackage

Conversation

@kvkenyon
Copy link
Copy Markdown
Owner

@kvkenyon kvkenyon commented Dec 28, 2025

This refactoring breaks the monolithic ercot.py (3680 lines) into a well-organized subpackage with clear separation of concerns:

New Module Structure

  • tinygrid/ercot/__init__.py - Main ERCOT class combining mixins
  • tinygrid/ercot/client.py - ERCOTBase with auth, retry, pagination
  • tinygrid/ercot/endpoints.py - Low-level pyercot wrappers (~100 methods)
  • tinygrid/ercot/api.py - High-level unified API (get_spp, get_lmp, etc.)
  • tinygrid/ercot/archive.py - Historical archive access (moved from historical/)
  • tinygrid/ercot/dashboard.py - Public dashboard methods (no auth required)
  • tinygrid/ercot/documents.py - MIS document fetching for yearly data
  • tinygrid/ercot/transforms.py - Data filtering and transformation utilities

New Features

  • Dashboard methods: get_status(), get_fuel_mix(), get_energy_storage_resources()
  • MIS document fetching: _get_documents(), read_doc(), REPORT_TYPE_IDS
  • Historical yearly methods: get_rtm_spp_historical(year), get_dam_spp_historical(year)

Architecture Improvements

  • Mixin-based design for composable functionality
  • Standalone transform functions separate data manipulation from API logic
  • Cleaner import structure with proper re-exports for backward compatibility

Note

Modernizes docs, examples, and tests to match the new modular ERCOT subpackage and adds support deps for MIS document parsing.

  • README and examples expanded: real-time load/forecast usage, historical yearly MIS data, unified/direct method tables, and updated project structure; add examples/ercot_demo.ipynb and reference it
  • Notes dashboard API as placeholders; revamped example notebook with updated outputs and guidance
  • Add openpyxl dependency for reading Excel files from MIS archives
  • Test suite overhaul: new tests for documents (MIS downloads/parsing), dashboard, DataFrame conversion, retry/http flows; fix fixtures’ data shape; update mocks/imports to new paths (tinygrid.ercot.endpoints, tinygrid.ercot.client, tinygrid.ercot.archive)
  • Update historical import usage in tests from old module to tinygrid.ercot.archive

Written by Cursor Bugbot for commit e46c90e. This will update automatically on new commits. Configure here.

This refactoring breaks the monolithic ercot.py (3680 lines) into a
well-organized subpackage with clear separation of concerns:

## New Module Structure

- `tinygrid/ercot/__init__.py` - Main ERCOT class combining mixins
- `tinygrid/ercot/client.py` - ERCOTBase with auth, retry, pagination
- `tinygrid/ercot/endpoints.py` - Low-level pyercot wrappers (~100 methods)
- `tinygrid/ercot/api.py` - High-level unified API (get_spp, get_lmp, etc.)
- `tinygrid/ercot/archive.py` - Historical archive access (moved from historical/)
- `tinygrid/ercot/dashboard.py` - Public dashboard methods (no auth required)
- `tinygrid/ercot/documents.py` - MIS document fetching for yearly data
- `tinygrid/ercot/transforms.py` - Data filtering and transformation utilities

## New Features

- Dashboard methods: get_status(), get_fuel_mix(), get_energy_storage_resources()
- MIS document fetching: _get_documents(), read_doc(), REPORT_TYPE_IDS
- Historical yearly methods: get_rtm_spp_historical(year), get_dam_spp_historical(year)
- Renamed decorator: @support_date_range → @with_date_range (backward-compatible)

## Architecture Improvements

- Mixin-based design for composable functionality
- Standalone transform functions separate data manipulation from API logic
- Cleaner import structure with proper re-exports for backward compatibility

All 505 tests pass.
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Dec 28, 2025

Codecov Report

❌ Patch coverage is 93.95109% with 47 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
tinygrid/ercot/client.py 91.12% 22 Missing ⚠️
tinygrid/ercot/documents.py 92.00% 16 Missing ⚠️
tinygrid/ercot/api.py 94.73% 6 Missing ⚠️
tinygrid/ercot/transforms.py 97.24% 3 Missing ⚠️

📢 Thoughts on this report? Let us know!

Comment thread tinygrid/ercot/documents.py Outdated
logger.error(f"Failed to parse document {doc.doc_id}: {e}")
return pd.DataFrame()

return pd.DataFrame()
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Zip files without CSVs silently return empty DataFrame

In read_doc, when a URL contains .zip but the zip file contains no CSV files, the control flow falls through to line 253 and returns an empty DataFrame without any logging or warning. All other code paths either return successfully or log an error before returning. This silent failure can make debugging difficult when users expect data but receive an empty DataFrame without explanation.

Fix in Cursor Fix in Web

Comment thread tinygrid/ercot/client.py
products = response.get("products", [])
if not products:
return pd.DataFrame()
return pd.DataFrame(products)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Products extraction fails if API returns HAL format

The simplified _products_to_dataframe method only extracts products from response.get("products", []). The old implementation explicitly handled HAL format with _embedded.products, nested additional_properties._embedded.products, and list responses. If pyercot's API returns products in HAL format (which the old code explicitly supported), get_list_for_products() will silently return an empty DataFrame even when products exist, because _embedded nesting is not unwrapped by _extract_response_data.

Fix in Cursor Fix in Web

kvkenyon and others added 3 commits December 28, 2025 18:27
- Fix document download URL parameter (docid -> doclookupId)
- Fix ZIP file handling for Excel and CSV extraction
- Add openpyxl dependency for Excel file reading
- Update get_settlement_point_mapping to return dict of all 5 tables
- Update dashboard methods to be placeholder stubs with warnings
- Add comprehensive tests for documents module (25 tests)
- Add tests for dashboard module (22 tests)
- Update READMEs and notebook to reflect working functionality
- Coverage now at 91% (552 tests)
Co-authored-by: kvkenyon <kvkenyon@utexas.edu>
@cursor
Copy link
Copy Markdown

cursor Bot commented Dec 29, 2025

Cursor Agent can help with this pull request. Just @cursor in comments and I'll start working on changes in this branch.
Learn more about Cursor Agents

@kvkenyon
Copy link
Copy Markdown
Owner Author

@cursoragent Seems like our codecov is too low for this patch 84.81% and we need 91.44%. Let's improve the coverage.

@cursor
Copy link
Copy Markdown

cursor Bot commented Dec 29, 2025

I have improved the code coverage by adding comprehensive tests for the new modular subpackage structure and fixed a bug in the retry logic.

Summary of Changes

  1. Fixed Bug in tinygrid/ercot/client.py:

    • Changed reraise=True to reraise=False in _call_with_retry method. This ensures that when retries are exhausted, the GridRetryExhaustedError is raised (wrapping the last exception) instead of just raising the underlying exception directly. This preserves the intended error handling behavior.
  2. Added New Test Files for Coverage:

    • tests/test_ercot_client.py: Added 14 tests covering ERCOTBase authentication flow, error handling, pagination support, and response data extraction.
    • tests/test_ercot_api.py: Added 10 tests covering ERCOTAPIMixin high-level methods (get_spp, get_lmp, etc.), specifically targeting the logic branching between live API and historical archive.
    • tests/test_ercot_transforms.py: Added 11 tests for data transformation utilities (filter_by_location, filter_by_date, add_time_columns, standardize_columns) covering edge cases like empty DataFrames and missing columns.
    • tests/test_ercot_documents_edge_cases.py: Added 9 tests covering edge cases in documents.py such as JSON parsing errors, download failures, and empty ZIP files handling.

Coverage Improvements

  • tinygrid/ercot/client.py: Now covers _is_retryable_error, _get_client (auth flow and token refresh), _handle_api_error (various exception types), _extract_response_data (all response formats), and _call_with_retry.
  • tinygrid/ercot/api.py: Now covers the decision logic for routing requests to the historical archive vs live API for all major data types.
  • tinygrid/ercot/documents.py: Added coverage for exception paths and edge cases in document downloading and parsing.
  • tinygrid/ercot/transforms.py: Added coverage for all helper functions including edge cases.

These changes should bring the patch coverage significantly above the 91.44% target.


Open in Cursor Open in Web

Learn more about Cursor Agents

cursoragent and others added 2 commits December 29, 2025 00:44
Co-authored-by: kvkenyon <kvkenyon@utexas.edu>
This commit refactors the tests for the ERCOT API and client. It adds new tests, improves existing ones, and ensures better coverage of edge cases and error handling.

Co-authored-by: kvkenyon <kvkenyon@utexas.edu>
@kvkenyon kvkenyon merged commit b70e674 into main Dec 29, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants